﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using GCC.APIContainer.Utilities;
using GCC.Container.Abstracts;
using GCC.Container.Models;

using Microsoft.AspNetCore.Mvc;

using tcm.entity;
using tcm.entity.Device;
using tcm.Filters;
using tcm.request;
using tcm.response;
using tcm.utils;

using WxPayAPI;

namespace tcm.Controller
{
    [ApiController]
    [Route("tcm/facility")]
    public class FacilityController : GCCAPIControllerBase
    {
        private readonly AbsGCCContext _context;
        public FacilityController(AbsGCCContext context) : base(context)
        {
            _context = context;
        }


        /// <summary>
        /// 1.绑定mac设备
        /// </summary>
        /// <returns></returns>
        [HttpGet("getUser/{mac}")]
        [TCMAuth(permission: "facility")]
        public ApiResult GetUserStaus([FromRoute] string mac)
        {
            if (string.IsNullOrWhiteSpace(mac))
                return new ApiResult() { code=400, msg="mac不能为空" };

            var user = GCCEntrance.DBManager!.LocalDB!.Queryable<User>().Where(x => x.tmp_mac==mac).First();
            var data = new UserStausRes();
            if (user!=null)
            {
                data.user_id=user.id;
                data.type=user.type;
                data.login_staus="true";
                if (!string.IsNullOrWhiteSpace(user.id_card))
                    data.is_has_idcard="true";
                else
                    data.is_has_idcard="false";

                var res = GCCEntrance.DBManager!.LocalDB!.Update<User>(user.id)
                .Set(item => item.tmp_mac, string.Empty)
                .ExecuteAffrows()==1;
            }
            else
            {
                data.login_staus="false";
                data.is_has_idcard="false";
            }
            return new ApiResult() { code=200, msg="success", data=data };
        }


        /// <summary>
        /// 2.实名认证
        /// </summary>
        /// <returns></returns>
        [HttpPut("authCard")]
        [TCMAuth(permission: "facility")]
        public ApiResult SaveCard([FromBody] AuthDto dto)
        {
            if (dto==null || string.IsNullOrEmpty(dto.id_card)|| dto.user_id<=0)
                return new ApiResult() { code=400, msg="请求信息不全" };

            var res = GCCEntrance.DBManager!.LocalDB!.Update<User>(dto.user_id)
               .Set(item => item.id_card, dto.id_card)
               .Set(item => item.uname, dto.user_name)
               .Set(item => item.sex, dto.sex)
               .Set(item => item.country, dto.country)
               .Set(item => item.val_date, dto.val_date)
               .Set(item => item.nation, dto.nation)
               .Set(item => item.address, dto.address)
               .ExecuteAffrows()==1;

            if (res)
                return new ApiResult() { code=200, msg="success" };

            return new ApiResult() { code=400, msg="未更新成功，找不到用户" };
        }



        //4.获取诊断报告


        //5.获取订单明细


        /// <summary>
        /// 6.获取订单支付结果
        /// </summary>
        /// <returns></returns>
        [HttpGet("getPayResult/{order_no}")]
        [TCMAuth(permission: "facility")]
        public ApiResult GetPayResult([FromRoute] long order_no)
        {
            if (order_no<=0)
                return new ApiResult() { code=400, msg="请输入订单编号" };

            var order = GCCEntrance.DBManager!.LocalDB!.Queryable<Order>().Where(x => x.id==order_no).First();
            var data = new PayResultRes();
            if (order!=null)
            {

                int pay_status = order.pay_status;
                if (pay_status == 2)
                {
                    // 待支付，查询微信支付状态
                    WxPayData queryOrderInput = new WxPayData();
                    queryOrderInput.SetValue("out_trade_no", order.out_trade_no);
                    WxPayData result = WxPayApi.OrderQuery(queryOrderInput);

                    if (result.GetValue("return_code").ToString() == "SUCCESS"
                        && result.GetValue("result_code").ToString() == "SUCCESS")
                    {
                        //支付成功
                        if (result.GetValue("trade_state").ToString() == "SUCCESS")
                        {
                            pay_status = 1;
                            _ = GCCEntrance.DBManager.GlobalDB.Update<Order>(order.id).Set(a => a.pay_status == 1).Set(a => a.pay_date == DateTime.Now).ExecuteAffrows();
                        }
                    }
                    else if (result.GetValue("err_code").ToString() == "ORDERNOTEXIST")
                    {
                        // 如果返回错误码为“此交易订单号不存在”则直接认定失败 支付异常
                        pay_status = 3;
                        _ = GCCEntrance.DBManager.GlobalDB.Update<Order>(order.id).Set(a => a.pay_status == 3).ExecuteAffrows();
                    }
                }

                data.order_no = order_no;
                data.order_pay_status= pay_status;
            }
            else
            {
                return new ApiResult() { code=400, msg="找不到订单信息" };
            }
            return new ApiResult() { code=200, msg="success", data=data };
        }

        /// <summary>
        /// 7.获取库存信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("getStock/{order_no}")]
        [TCMAuth(permission: "facility")]
        public ApiResult GetStock([FromRoute] long order_no)
        {
            if (order_no<=0)
                return new ApiResult() { code=400, msg="请输入订单编号" };

            var order = GCCEntrance.DBManager!.LocalDB!.Queryable<Order>().Where(x => x.id==order_no).First();
            var data = new CabinetRes();
            if (order!=null)
            {
                var model = GCCEntrance.DBManager!.LocalDB!.Select<Cabinet, Device>()
                    .LeftJoin((c, d) => c.device_id==d.id)
                    .Where((c, d) => c.id==order.cabinet_id)
                    .First((c, d) => new { c, d });
                if (model!=null)
                {
                    data.is_phm_list=model.c.is_have==1 ? "true" : "fasle";
                    data.cabinet_no=model.c.cabinet_no;
                    data.mac=model.d?.mac;
                }
            }
            else
            {
                return new ApiResult() { code=400, msg="找不到订单信息" };
            }
            return new ApiResult() { code=200, msg="success", data=data };
        }

        /// <summary>
        /// 8.提交预约信息
        /// </summary>
        /// <returns></returns>
        [HttpPut("appointment")]
        [TCMAuth(permission: "facility")]
        public ApiResult SaveAppointment([FromBody] AppointmentDto dto)
        {
            if (dto==null || dto.order_no<=0)
                return new ApiResult() { code=400, msg="请求信息不全" };

            if (dto.start_date==null || dto.end_date==null ||  dto.end_date< dto.start_date)
                return new ApiResult() { code=400, msg="输入的时间不正确，结束时间必须大于开始时间" };

            var res = GCCEntrance.DBManager!.LocalDB!.Update<Order>().Where(x => x.id==dto.order_no)
               .Set(item => item.start_date, dto.start_date)
               .Set(item => item.end_date, dto.end_date)
               .Set(item => item.status, 2)
               .ExecuteAffrows()==1;

            if (res)
                return new ApiResult() { code=200, msg="success" };

            return new ApiResult() { code=400, msg="未更新成功" };
        }

        /// <summary>
        /// 9.获取未完成流程
        /// </summary>
        /// <returns></returns>
        [HttpGet("unprocess")]
        [TCMAuth(permission: "facility")]
        public ApiResult GetOrderByUserId([FromQuery] long user_id, int? status = null)
        {
            if (user_id<=0)
                return new ApiResult() { code=400, msg="用户ID不能为空" };

            var statusList = new List<int> { 0, 1, 2, 3, 4, 5 };
            var data = new List<OrderProcessRes>();
            var order = GCCEntrance.DBManager!.LocalDB!.Select<Order, UserReport>()
                .LeftJoin((o, u) => o.id == u.order_id)
                .Where((o, u) => o.user_id==user_id &&statusList.Contains(o.status))
                .WhereIf(status.HasValue, (o, u) => u.status != status)
                .ToList();

            if (order!=null)
            {
                foreach (var item in order)
                {
                    data.Add(new OrderProcessRes()
                    {
                        order_no=item.id,
                        order_pay_status=item.pay_status,
                        pay_type=item.pay_type,
                        price=item.price
                    });
                }
                return new ApiResult() { code=200, msg="success", data=data };
            }
            else
            {
                return new ApiResult() { code=400, msg="没有未支付的订单" };
            }
        }

        /// <summary>
        /// 10.获取配送员配送清单明细
        /// </summary>
        /// <returns></returns>
        [HttpGet("supplyList/{user_id}")]
        [TCMAuth(permission: "facility")]
        public ApiResult GetSupplyList([FromRoute] long user_id)
        {
            if (user_id<=0)
                return new ApiResult() { code=400, msg="用户ID不能为空" };

            var list = GCCEntrance.DBManager!.LocalDB!.Select<Order, Cabinet, Device>()
                .LeftJoin((o, c, d) => o.cabinet_id==c.id)
                .LeftJoin((o, c, d) => c.device_id==d.id)
                .Where((o, c, d) => o.delivery_id==user_id&& o.status==3)
                .ToList((o, c, d) => new { o, c, d });

            var data = new List<OrderDrugsRes>();

            foreach (var item in list)
            {
                if (item.o!=null)
                {
                    var phmList = GCCEntrance.DBManager!.LocalDB!.Select<UesrPhmList>()
                    .Where(p => p.order_id==item.o.id).ToList();

                    if (phmList!=null)
                    {
                        var phmIds = phmList.GroupBy(x => x.phm_id).Distinct().Select(x => x.Key).ToList();

                        var pharmaceutical = GCCEntrance.DBManager!.LocalDB!.Select<Pharmaceutical>()
                         .Where(p => phmIds.Contains(p.id)).ToList();
                        foreach (var product in pharmaceutical)
                        {
                            var phm = phmList.Where(p => p.phm_id==product.id).FirstOrDefault();
                            data.Add(new OrderDrugsRes()
                            {
                                order_no=item.o.id,
                                phm_list_id=phm.id,
                                num=phm.num,
                                phm_no=product.phm_no,
                                pname=product.pname,
                                price=product.price,
                                mac=item.d?.mac,
                                cabinet_no=item.c?.cabinet_no,
                                container_no=item.c?.container_no
                            });
                        }
                    }
                }
            }

            return new ApiResult() { code=200, msg="success", data=data };
        }

        /// <summary>
        ///  11.上报配送结果
        /// </summary>
        /// <param name="order_no"></param>
        /// <returns></returns>
        [HttpPut("reportSupply")]
        [TCMAuth(permission: "facility")]
        public ApiResult SaveSupplyResults([FromBody] ReportSupplyDto reportSupplyDto)
        {
            if (reportSupplyDto.order_no<=0)
                return new ApiResult() { code=400, msg="请传入订单编号" };

            try
            {
                var msg = string.Empty;
                GCCEntrance.DBManager!.LocalDB!.Transaction(() =>
                {
                    var dto = new BaseExtensionDto();
                    dto.Create(_context, HttpContext.GetToken()).Wait();
                    var data = GCCEntrance.DBManager!.LocalDB!.Select<Order, Cabinet>()
                       .InnerJoin((o, c) => o.cabinet_id==c.id)
                       .Where((o, c) => o.id==reportSupplyDto.order_no)
                       .First((o, c) => new { o, c });

                    var userPhm = GCCEntrance.DBManager!.LocalDB!.Select<UesrPhmList>()
                       .Where(p => p.order_id == data.o.id)
                       .OrderByDescending(p => p.create_date)
                       .First();

                    if (data!=null && userPhm != null)
                    {
                        var status = data.o.status;
                        var num = data.c.num;
                        var isUse = data.c.is_use;
                        var ishave = data.c.is_have;
                        var info = new PhmLog()
                        {
                            id=dto.id,
                            cabinet_id=data.c.id,
                            num=1,
                            instructions="",
                            phm_list_id=userPhm.phm_list_id,
                            create_by=dto.create_by,
                            create_date=dto.create_date,
                            update_by=dto.update_by,
                            update_date=dto.update_date,
                        };

                        //药斗配送
                        if (reportSupplyDto.order_type==1)
                        {
                            status=6;
                            //var phmListRelation = GCCEntrance.DBManager!.LocalDB!.Select<PhmListRelation>()
                            //.Where(p => p.phm_list_id==userPhm.phm_list_id)
                            //.First();
                            info.num=userPhm.num;
                            num+=userPhm.num;
                            ishave=1;
                            info.phm_use=1;
                            info.instructions="药斗配送";
                        }
                        else
                        {
                            //快递员
                            if (reportSupplyDto.type==1)
                            {
                                info.phm_use=1;
                                info.instructions="配送员配送";
                                num++;
                                status=5;
                                ishave=1;
                            }
                            else
                            {
                                var quantity = 0;
                                var device = GCCEntrance.DBManager!.LocalDB!.Select<Device>()
                                .Where(p => p.id==data.c.device_id)
                                .First();

                                if (device.device_name.Contains("药斗"))
                                {
                                    var phmListRelation = GCCEntrance.DBManager!.LocalDB!.Select<PhmListRelation>()
                                      .Where(p => p.phm_list_id==userPhm.phm_list_id)
                                      .First();
                                    info.num=phmListRelation.phm_num;
                                    num-=phmListRelation.phm_num;
                                }
                                else
                                {
                                    num--;
                                }
                                info.phm_use=2;
                                info.instructions="用户取药";
                                status=6;
                                isUse=0;
                                if (num<=-1)
                                {
                                    throw new Exception("库存不足，无法取药");
                                }
                                if (num==0)
                                    ishave=0;
                                else if (num >0)
                                    ishave=1;
                            }
                        }

                        //插入出入库记录
                        if (GCCEntrance.DBManager!.LocalDB!.Insert(info).ExecuteAffrows() != 1)
                        {
                            throw new Exception();
                        }

                        //更新库存
                        if (GCCEntrance.DBManager!.LocalDB!.Update<Cabinet>().Where(x => x.id==data.c.id)
                           .Set(item => item.num, num)
                           .Set(item => item.is_have, ishave)
                           .Set(item => item.is_use, isUse)
                           .ExecuteAffrows()!=1)
                        {
                            throw new Exception();
                        }

                        //更新订单状态
                        if (GCCEntrance.DBManager!.LocalDB!.Update<Order>().Where(x => x.id==reportSupplyDto.order_no)
                          .Set(item => item.status, status)
                          .ExecuteAffrows()!=1)
                        {
                            throw new Exception();
                        }

                        //配送完成
                        if (reportSupplyDto.type==1&& reportSupplyDto.order_type==0)
                        {
                            msg = WeChatSendMessage.Instance.OrderSupplyNotice(reportSupplyDto.order_no);
                            if (!string.IsNullOrWhiteSpace(msg))
                                Logger.Error(string.Format("上报配送结果用户推送消息失败：{0}。", msg), _context.EventID);
                            Logger.Information(string.Format("向用户推送药品入柜消息成功，订单编号{0}。", reportSupplyDto.order_no), _context.EventID);
                        }

                    }
                    else
                    {
                        throw new Exception("找不到药柜信息");
                    }

                });

                if (!string.IsNullOrEmpty(msg))
                {
                    throw new Exception("上报配送结果用户推送消息失败"+msg);
                }


            }
            catch (Exception exc)
            {
                Logger.Error(String.Format("上报配送结果异常：{0}。", exc.Message), _context.EventID, exc);
                return new ApiResult() { code=400, msg="未更新成功,"+exc.Message };
            }

            return new ApiResult() { code=200, msg="success" };

        }



        /// <summary>
        /// 12.获取站点信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("getSite/{mac}")]
        [TCMAuth(permission: "facility")]
        public ApiResult GetSiteByMac([FromRoute] string mac)
        {
            if (string.IsNullOrWhiteSpace(mac))
                return new ApiResult() { code=400, msg="mac不能为空" };


            var device = GCCEntrance.DBManager!.LocalDB!.Select<Site>()
                .Where(d => d.mac==mac.Trim()).First();

            return new ApiResult() { code=200, msg="success", data=device };
        }



        /// <summary>
        /// 13.根据站点id获取库存列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("getCabinetList/{siteId}")]
        [TCMAuth(permission: "facility")]
        public ApiResult GetSiteByMac([FromRoute] long siteId)
        {
            if (siteId<=0)
                return new ApiResult() { code=400, msg="站点ID格式不正确" };

            var device = GCCEntrance.DBManager!.LocalDB!.Select<Cabinet, Device, Site>()
                .LeftJoin((c, d, s) => c.device_id==d.id)
                .LeftJoin((c, d, s) => d.site_id==s.id)
                .Where((c, d, s) => s.id==siteId && d.device_name.Contains("药斗"))
                .ToList();

            return new ApiResult() { code=200, msg="success", data=device };
        }

    }
}
